home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / XPK / Source / libraries / RLEN / xpkRLEN.c_o < prev    next >
Encoding:
Text File  |  1997-04-01  |  2.8 KB  |  145 lines

  1. /*
  2.  * This library is mainly intended to demonstrate how to program a sub
  3.  * library.
  4.  */
  5.  
  6. char ver[]= "$VER: RLEN 1.1 (" __DATE__ ")";
  7.  
  8. #define NO_SUB_PRAGMAS
  9.  
  10. #include <libraries/xpksub.h>
  11.  
  12. #define A3000 XPKMF_A3000SPEED
  13.  
  14. XMINFO RlenMode =
  15. {
  16.   NULL,                /* next            */
  17.   100,                /* upto            */
  18.   A3000,            /* flags        */
  19.   0,                /* packmem        */
  20.   0,                /* unpackmem        */
  21.   140,                /* packspeed, K / sec    */
  22.   1043,                /* unpackspeed, K / sec    */
  23.   45,                /* ratio, *0.1 %    */
  24.   0,                /* reserved        */
  25.   "normal"            /* description        */
  26. };
  27.  
  28. static struct XpkInfo RlenInfo =
  29. {
  30.   1,                /* info version */
  31.   1,                /* lib  version */
  32.   0,                /* master vers  */
  33.   0,                /* pad          */
  34.   "RLEN",            /* short name   */
  35.   "Run Length 1.1",        /* long name    */
  36.   "Fast and simple compression usable for simple data",    /* description*/
  37.   'RLEN',            /* 4 letter ID  */
  38.   XPKIF_PK_CHUNK |        /* flags        */
  39.   XPKIF_UP_CHUNK,
  40.   0x7fffffff,            /* max in chunk */
  41.   0,                /* min in chunk */
  42.   0x4004,            /* def in chunk */
  43.   NULL,                /* pk message   */
  44.   NULL,                /* up message   */
  45.   NULL,                /* pk past msg  */
  46.   NULL,                /* up past msg  */
  47.   50,                /* def mode     */
  48.   0,                /* pad          */
  49.   &RlenMode            /* modes        */
  50. };
  51.  
  52. /*
  53.  * Returns an info structure about our packer
  54.  */
  55. struct XpkInfo *__saveds __asm
  56. XpksPackerInfo (void)
  57. {
  58.   return &RlenInfo;
  59. }
  60.  
  61.  
  62. void __saveds __asm
  63. XpksPackFree (register __a0 XPARAMS * xpar)
  64. {
  65. }
  66.  
  67. /*
  68.  * This forces the next chunk to be uncompressable independent from the
  69.  * previous one. This is always the case in RLEN.
  70.  */
  71. long __saveds __asm
  72. XpksPackReset (register __a0 XPARAMS * xpar)
  73. {
  74.   return 0;
  75. }
  76.  
  77.  
  78. void __saveds __asm
  79. XpksUnpackFree (register __a0 XPARAMS * xpar)
  80. {
  81. }
  82.  
  83. /*
  84.  * Pack a chunk
  85.  */
  86. long __saveds __asm
  87. XpksPackChunk (register __a0 XPARAMS * xpar)
  88. {
  89.   UBYTE *get = xpar->InBuf, *start = xpar->InBuf;
  90.   UBYTE *end = get + xpar->InLen, *put = xpar->OutBuf;
  91.   UBYTE *wend = put + xpar->OutBufLen;
  92.   int run, i;
  93.  
  94.   for (;;) {
  95.     run = get[0] == get[1] && get[1] == get[2];
  96.  
  97.     if (put + (get - start) + 4 > wend)
  98.       return XPKERR_EXPANSION;
  99.  
  100.     if (run || get - start == 127 || get == end) {    /* write uncompressed */
  101.       if (get - start) {
  102.     *put++ = get - start;
  103.     for (i = get - start; i > 0; i--)
  104.       *put++ = *start++;
  105.       }
  106.       if (get == end) {
  107.     *put++ = 0;
  108.     break;
  109.       }
  110.       start = get;
  111.     }
  112.  
  113.     if (run) {            /* write compressed   */
  114.       for (i = 3; get + i < end && get[i - 1] == get[i] && i < 127; i++);
  115.       *put++ = -i;
  116.       *put++ = get[0];
  117.       get += i;
  118.       start = get;
  119.     }
  120.     else
  121.       get++;
  122.   }
  123.   xpar->OutLen = put - (UBYTE *) xpar->OutBuf;
  124.  
  125.   return 0;
  126. }
  127.  
  128.  
  129. long __saveds __asm
  130. XpksUnpackChunk (register __a0 XPARAMS * xpar)
  131. {
  132.   char *get = xpar->InBuf, *put = xpar->OutBuf, v;
  133.   int i;
  134.  
  135.   while (i = *get++)
  136.     if (i > 0)
  137.       for (; i > 0; i--)
  138.     *put++ = *get++;
  139.     else
  140.       for (i = -i, v = *get++; i > 0; i--)
  141.     *put++ = v;
  142.  
  143.   return 0;
  144. }
  145.